/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2024. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mmpa_api.h"
#include <iostream>

uint32_t mmSetData(mmAtomicType *ptr, uint32_t value) {
  return __sync_lock_test_and_set(ptr, value);
}

uint64_t mmSetData64(mmAtomicType64 *ptr, uint64_t value) {
  return __sync_lock_test_and_set(ptr, value);
}

uint32_t mmValueInc(mmAtomicType *ptr, uint32_t value) {
  return __sync_fetch_and_add(ptr, value);
}

bool mmCompareAndSwap(mmAtomicType *ptr, uint32_t oldval, uint32_t newval) {
  return __sync_bool_compare_and_swap(ptr, oldval, newval);
}

bool mmCompareAndSwap64(mmAtomicType *ptr, uint32_t oldval, uint32_t newval) {
  return __sync_bool_compare_and_swap(ptr, oldval, newval);
}

void mmValueStore(mmAtomicType *ptr, uint32_t value) {
  __atomic_store(ptr, &value, __ATOMIC_SEQ_CST);
}

int32_t mmMutexInit(mmMutex_t *mutex) {
  return pthread_mutex_init(mutex, NULL);
}

int32_t mmMutexLock(mmMutex_t *mutex) {
  return pthread_mutex_lock(mutex);
}

int32_t mmMutexUnLock(mmMutex_t *mutex) {
  return pthread_mutex_unlock(mutex);
}

int32_t mmMutexDestroy(mmMutex_t *mutex) {
  return pthread_mutex_destroy(mutex);
}

void mmSchedYield(void) {
  (void)sched_yield();
}

uint64_t mmGetTaskId(void) {
  return (uint64_t)(syscall(SYS_gettid));
}

mmFileHandle *mmOpenFile(const char *fileName, int32_t mode) {
  mmFileHandle *fd = NULL;
  if (mode == FILE_READ) {
    fd = fopen(fileName, "r");
  }
  if (mode == FILE_READ_BIN) {
    fd = fopen(fileName, "rb");
  }
  return fd;
}

size_t mmReadFile(void *ptr, int32_t size, int32_t nitems, mmFileHandle *fd) {
  return fread(ptr, (size_t)size, (size_t)nitems, fd);
}

int32_t mmCloseFile(mmFileHandle *fd) {
  return fclose(fd);
}
int32_t mmRealPath(const char *path, char *realPath, int32_t realPathLen) {
  (void)realPathLen;
  return realpath(path, realPath) == NULL ? EN_ERROR : EN_OK;
}
int32_t mmAccess(const char *pathName, int32_t mode) {
  return access(pathName, mode);
}

int32_t mmSeekFile(mmFileHandle *fd, int64_t offset, int32_t seekFlag) {
  return fseek(fd, (long)offset, seekFlag);
}

long mmTellFile(mmFileHandle *fd) {
  return ftell(fd);
}

void *mmMalloc(unsigned long long size) {
  return MmpaStubMock::GetInstance().mmMalloc(size);
}

void *mmMalloc_Normal_Invoke(unsigned long long size) {
  std::cout<<"called mmMalloc_Normal_Invoke!"<<std::endl;
  return malloc(size);
}

void *mmMalloc_Abnormal_Invoke(unsigned long long size) {
  std::cout<<"called mmMalloc_AbNormal_Invoke!"<<std::endl;
  size++;
  return NULL;
}

void mmFree(void *ptr) {
  free(ptr);
}